package ext.workflow;
import java.lang.reflect.InvocationTargetException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Vector;

import wt.access.AccessControlHelper;
import wt.access.AdHocAccessKey;
import wt.access.AdHocControlled;
import wt.doc.WTDocument;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.PersistenceServerHelper;
import wt.fc.QueryResult;
import wt.fc.ReferenceFactory;
import wt.fc.WTObject;
import wt.inf.container.ExchangeContainer;
import wt.inf.container.WTContained;
import wt.inf.container.WTContainer;
import wt.inf.container.WTContainerHelper;
import wt.inf.team.ContainerTeam;
import wt.inf.team.ContainerTeamHelper;
import wt.inf.team.ContainerTeamManaged;
import wt.method.RemoteAccess;
import wt.org.OrganizationServicesHelper;
import wt.org.PrincipalCollationKeyFactory;
import wt.org.WTGroup;
import wt.org.WTOrganization;
import wt.org.WTPrincipal;
import wt.org.WTPrincipalReference;
import wt.org.WTUser;
import wt.pom.Transaction;
import wt.project.Role;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.session.SessionServerHelper;
import wt.team.Team;
import wt.team.TeamHelper;
import wt.team.TeamManaged;
import wt.type.ClientTypedUtility;
import wt.util.SortedEnumeration;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
import wt.workflow.engine.WfActivity;
import wt.workflow.engine.WfBlock;
import wt.workflow.engine.WfContainer;
import wt.workflow.engine.WfProcess;
import wt.workflow.engine.WfVariable;
import wt.workflow.work.WorkItem;

public class WorkFlowUtil  implements RemoteAccess  {

	/**
	 * @param args
	 * @throws WTException 
	 * @throws InvocationTargetException 
	 * @throws RemoteException 
	 */
	public static void main(String[] args) throws WTException, RemoteException, InvocationTargetException {
		
	}
	

	
	//得到上下文团队的角色及角色中的成员
	public static Map<Role,List<WTUser>> getRoleAndUserByContainer(String oid) throws WTException {
	
		Map<Role,List<WTUser>> roleAndUserMap = new HashMap<Role,List<WTUser>>();
		ReferenceFactory rf = new ReferenceFactory();
		List<WTUser> userList = new ArrayList<WTUser>();

		if (oid != null) {
			boolean enforce = wt.session.SessionServerHelper.manager.setAccessEnforced(false);
			try {
				WorkItem wi = (WorkItem) rf.getReference(oid).getObject();
				WfActivity wfAct = (WfActivity) wi.getSource().getObject();

				Persistable pbo = (Persistable) wfAct.getContext().getValue("primaryBusinessObject");
				
				WTContained obj = (WTContained)pbo;
				WTContainer container = obj.getContainer();
	
				ContainerTeamManaged ctm = null;
				if(container instanceof ContainerTeamManaged){
					ctm = (ContainerTeamManaged)container;
				}
				ContainerTeam containerteam = ContainerTeamHelper.service.getContainerTeam(ctm);
				Vector vector = containerteam.getRoles();
	
				for (int i = 0; i < vector.size(); i++) {	
												
					List tempUserList = containerteam.getAllPrincipalsForTarget((Role) vector.get(i));
					Role role = (Role)vector.get(i);
					for (int j = 0; tempUserList != null && j < tempUserList.size(); j++) {
						WTPrincipalReference wtprincipalreference = (WTPrincipalReference) tempUserList.get(j);
						Persistable persistable = wtprincipalreference.getObject();
						if(persistable instanceof WTUser){
						
							userList.add((WTUser)persistable);	
						}else if (persistable instanceof WTGroup){
							List<WTUser> tempList = getGroupMembersOfUser((WTGroup)persistable);
							for(int k = 0 ; k < tempList.size() ; k ++){
								userList.add(tempList.get(k));
							}
						}
					}
					roleAndUserMap.put(role, userList);
					userList = new ArrayList<WTUser>();
				}
			} catch (WTException e) {
				e.printStackTrace();
			} finally {
				wt.session.SessionServerHelper.manager.setAccessEnforced(enforce);
			}
		}

		return roleAndUserMap;
	}
	
	//得到组里面的成员
	public static List<WTUser> getGroupMembersOfUser(WTGroup group)
	throws WTException {
	List<WTUser> users = new ArrayList<WTUser>();
	Enumeration member = group.members();
	
	while (member.hasMoreElements()) {
		WTPrincipal principal = (WTPrincipal) member.nextElement();
		if (principal instanceof WTUser) {
			users.add((WTUser) principal);
		} else if (principal instanceof WTGroup) {
			List<WTUser> ausers = getGroupMembersOfUser((WTGroup) principal);
			for (int i = 0; i < ausers.size(); i++) {
				users.add(ausers.get(i));
			}
		}
	}
		return users;
	}
	
	//根据组名得到组
	 public static WTGroup getGroup(String groupName)throws WTException {
		 
        ExchangeContainer exchangecontainer = WTContainerHelper.service.getExchangeContainer();
        
        WTOrganization wtorganization = exchangecontainer.getOrganization();
        
        WTGroup group = null;
        group = OrganizationServicesHelper.manager.getGroup(groupName,wtorganization);//组织下的组

        if(group ==null){
   			
   	 group = OrganizationServicesHelper.manager.getGroup(groupName,exchangecontainer.getContextProvider());//站点下的组
   		
        }
        if (group == null) {
	        throw new WTException("没有找到组: [" + groupName + "] ");
	    }
        return group;
}
	
	
	//根据WfProcess对象，获得团队
    public static Team getTeam(WfProcess process) throws Exception 
    {
	    
        Team team = null;
    	ReferenceFactory rf = new ReferenceFactory();
	    String oid = rf.getReferenceString(process);
        WTObject wtobject = (WTObject) rf.getReference(oid).getObject();
        if (wtobject instanceof TeamManaged) {
          team = (Team) ( (TeamManaged) wtobject).getTeamId().getObject();
        }
        else
        if (wtobject instanceof Team) {
          team = (Team) wtobject;
          //Vector v = team.getMembers();
          
        }
        return team;
      }
    
    //查找所有的用户
	public  static List<WTUser> getAllUser() throws WTException {
		List<WTUser> userList = new ArrayList<WTUser>();
		boolean enforce = wt.session.SessionServerHelper.manager
				.setAccessEnforced(false);
		try {
			QuerySpec qs = new QuerySpec(WTUser.class);
			QueryResult qr = PersistenceHelper.manager.find(qs);
			while (qr.hasMoreElements()) {
				WTUser user = (WTUser) qr.nextElement();
				if (!user.isDisabled())
					userList.add(user);
			}
		} catch (WTException e) {
			e.printStackTrace();
		} finally {
			wt.session.SessionServerHelper.manager.setAccessEnforced(enforce);
		}
		return userList;
	}
	
	//根据用户名查询WTUser对象
	public static  WTUser GetUserByName(String username) throws WTException
	{
		WTUser user = null ;
		QuerySpec qs = new QuerySpec(WTUser.class);
		SearchCondition sc = new SearchCondition(WTUser.class,WTUser.NAME,"=",username);
		qs.appendWhere(sc);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		while(qr.hasMoreElements())
		{
			user = (WTUser)qr.nextElement();
		}
		return user;
	}
    
	//根据用户名或者全名查找用户
	public static List<WTUser> getUserByName(String userName) throws WTException {
		List<WTUser> results = new ArrayList<WTUser>();
		Locale locale = Locale.CHINA;
		boolean enforce = wt.session.SessionServerHelper.manager.setAccessEnforced(false);
		try {
			Enumeration usernames = OrganizationServicesHelper.manager.findUser("fullName", userName);
			if (usernames != null) {
				while (usernames.hasMoreElements()) {
					WTUser curUser = (WTUser) usernames.nextElement();
					results.add(curUser);
				}
			}

			SortedEnumeration fullusernames = new SortedEnumeration(OrganizationServicesHelper.manager.findUser("name",userName), new PrincipalCollationKeyFactory(locale));
			if (fullusernames != null){
				while (fullusernames.hasMoreElements()) {
					WTUser curUser = (WTUser) fullusernames.nextElement();
					if (!results.contains(curUser) && !curUser.isDisabled()){
						results.add(curUser);
					}
				}
			}
		} catch (WTException e) {
			e.printStackTrace();
		} finally {
			wt.session.SessionServerHelper.manager.setAccessEnforced(enforce);
		}
		return results;
	}
	
	//根据用户名或者全名模糊查找用户
	public static List<WTUser> getUserLikeName(String criteria) throws WTException {
		List<WTUser> results = new ArrayList<WTUser>();
		Locale locale = Locale.CHINA;
		boolean enforce = wt.session.SessionServerHelper.manager.setAccessEnforced(false);
		try {
			Enumeration usernames = OrganizationServicesHelper.manager.findLikeUser("fullName", criteria);
			if (usernames != null) {
				while (usernames.hasMoreElements()) {
					WTUser curUser = (WTUser) usernames.nextElement();
					results.add(curUser);
				}
			}

			SortedEnumeration fullusernames = new SortedEnumeration(
			OrganizationServicesHelper.manager.findLikeUser("name",criteria), new PrincipalCollationKeyFactory(locale));
			if (fullusernames != null){
				while (fullusernames.hasMoreElements()) {
					WTUser curUser = (WTUser) fullusernames.nextElement();
					if (!results.contains(curUser) && !curUser.isDisabled()){
						results.add(curUser);
					}
				}
			}
		} catch (WTException e) {
			e.printStackTrace();
		} finally {
			wt.session.SessionServerHelper.manager.setAccessEnforced(enforce);
		}
		return results;
	}
    
    //给角色添加用户
    public static void addPrincipalToRole(WfProcess process, String internal_value, WTUser user)throws WTPropertyVetoException, WTException
	{
	    
	    wt.team.Team team = null;
	    try {
	        team = getTeam(process);
	    }
	    catch (Exception ex) {
	        ex.printStackTrace();
	        throw new WTException(ex);
	    }

	    Role theRole = Role.toRole(internal_value);
	    if (user == null) {
	        throw new WTException("没有找到用户: [" + user + "] ");
	    }
	    else
	    {
	        team.addPrincipal(theRole, user);
	    }
	    PersistenceHelper.manager.refresh(team);
	}
    
    /**
     * 批量设置流程角色
     * @param process 流程
     * @param internal_value 角色名称
     * @param users 用户
     * @param delHisUser 是否删除角色的历史用户
     * @throws WTPropertyVetoException
     * @throws WTException
     * @author xucr
     * @CreateDate 2020年6月10日
     */
    public static void addPrincipalToRole(WfProcess process, String internal_value, List<WTUser> users, boolean delHisUser)throws WTPropertyVetoException, WTException {
	    
	    wt.team.Team team = null;
	    try {
	        team = getTeam(process);
	    }
	    catch (Exception ex) {
	        ex.printStackTrace();
	        throw new WTException(ex);
	    }

	    Role theRole = Role.toRole(internal_value);
	    if (users == null || users.size() == 0) {
	        throw new WTException("没有传递实际用户");
	    } else {
	    	if(delHisUser) {
	    		//先移除原有的用户
	    		deleteProcessRoleHolder(team, theRole);
	    	}
	    	//再加入角色
	    	for(WTUser user : users) {
	    		 team.addPrincipal(theRole, user);
	    	}
	    }
	    PersistenceHelper.manager.refresh(team);
	}
    
    /**
     * 删除团队角色
     * @param team
     * @param role
     * @throws WTException
     * @author xucr
     * @CreateDate 2020年6月12日
     */
    public static void deleteProcessRoleHolder(Team team, Role role) throws WTException  {
    	if(null != team && null != role) {
    		Enumeration<?> roles = team.getPrincipalTarget(role);
    		while (roles.hasMoreElements()) {
    			WTPrincipalReference ref = (WTPrincipalReference) roles.nextElement();
    			if (ref != null) {
    				WTPrincipal principal = ref.getPrincipal();
    				team.deletePrincipalTarget(role, principal);
    			}
    		}
    	}
    }
	
     
	//获得工作流对象,传入的是workitem的oid
	public static  WfProcess GetWfProcess(String oid) throws WTException
	{	
		ReferenceFactory rf = new ReferenceFactory();
		WorkItem wi = (WorkItem) rf.getReference(oid).getObject();
		WfActivity wfAct = (WfActivity) wi.getSource().getObject();
		WfContainer wfcont = (WfContainer) wfAct.getParentProcessRef().getObject();
		WfProcess process = null;
		if (wfcont instanceof WfBlock) {
			WfBlock wfblock = (WfBlock)wfcont;
			process =wfblock.getParentProcess();
		} else {
			process = (WfProcess) wfcont;
		}
		
		return process;
		
	}
	
	/**
	 * 获取变量的值	 
	 * addButtonVar:变量名
	 */
	public static String getProcessVariable(WfProcess process,String addButtonVar){
		Object value = null;
		String addStr =  null;
		WfVariable testVariableMain = process.getContext().getVariable(addButtonVar);
		value = testVariableMain.getValue();
		if(value != null)
		{
			addStr = value.toString();
		}
		return addStr;
	}
	
	//根据流程中的角色，得到用户
	public static  ArrayList<WTUser>  getUserByRole(String oid,String roleValue) throws WTException {
		List<WTUser> userList = null;
		ReferenceFactory rf = new ReferenceFactory();
		boolean enforce = wt.session.SessionServerHelper.manager.setAccessEnforced(false);
		try {
			WorkItem wi = (WorkItem) rf.getReference(oid).getObject();
			WfActivity wfAct = (WfActivity) wi.getSource().getObject();

			WfProcess process = wfAct.getParentProcess();
			Team team = (Team) process.getTeamId().getObject();
			Map rolePrincipalListMap = TeamHelper.service.findAllParticipantsByRole(team);
			
	
			Role role = Role.toRole(roleValue);
			List tempList = (List) rolePrincipalListMap.get(role);
			userList = new ArrayList<WTUser>();
			if (tempList != null) {
				for (int j = 0; j < tempList.size(); j++) {
					userList.add((WTUser) ((WTPrincipalReference) tempList.get(j)).getObject());
				}
			}

		} catch (WTException e) {
			e.printStackTrace();
		} finally {
			wt.session.SessionServerHelper.manager.setAccessEnforced(enforce);
		}
		return (ArrayList<WTUser>) userList;

	}
	


    //得到流程中的角色及角色中的用户
    public static Map<Role,List<WTUser>>  getRoleAndUser(WfProcess wf)throws WTException
    {    
		Role role = null;//记录流程中的角色
		Map<Role,List<WTUser>> roleAndUserMap = new HashMap<Role,List<WTUser>>();
        List userList = new ArrayList<WTUser>();
        WTPrincipalReference wtprincipalreference = null;
        Persistable persistable  = null;
        WTUser wtuser = null;
        Team team = (Team)wf.getTeamId().getObject();
        
        
		try {
			Vector v = wf.getProcessRoles();
			
			//List v = getWorkflowRole(wf);
			
			for(int i = 0;i<v.size(); i++)
			{
				role = (wt.project.Role)v.get(i);
				Enumeration enumPrin = team.getPrincipalTarget(role);
			    while(enumPrin.hasMoreElements())
			    {
			    	wtprincipalreference = (WTPrincipalReference) enumPrin.nextElement();
			        persistable = wtprincipalreference.getObject();
					if(persistable instanceof WTUser)
					{
						wtuser = (WTUser)persistable;
						userList.add(wtuser);
					}
			    }
			    roleAndUserMap.put(role, userList) ;
			    userList = new ArrayList<WTUser>();
				
			}

		} catch (WTException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return roleAndUserMap; 
		
    }
    
	
	
	//获得流程中的角色
	public static List<Role>  getWorkflowRole(WfProcess process)
	{
		Role role = null;//记录流程中的角色
		List<Role> roleList = new ArrayList<Role>();
		try {
			Vector v = process.getProcessRoles();
			for(int i = 0;i<v.size(); i++)
			{
				role = (wt.project.Role)v.get(i);
				roleList.add(role);
			}

		} catch (WTException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return roleList; 

	}
	
	
	 //删除流程中所有的用户
	 public  static void deleteAllUser(WfProcess process) throws Exception 
	 {

		Role role = null;//记录流程中的角色
		Team team = null;
		team = getTeam(process);
	    Vector v = process.getProcessRoles();
	    String inter_value;
	    
		for(int i = 0;i<v.size(); i++)
		{
			role = (wt.project.Role)v.get(i);
			inter_value = role.toString();
		    Role theRole =  Role.toRole(inter_value);
		    Enumeration roles = team.getPrincipalTarget(theRole);
		    while (roles.hasMoreElements()) 
		    {
		      WTPrincipalReference ref = (WTPrincipalReference) roles. nextElement();
		      if (ref != null) 
		      {
		        WTPrincipal principal = ref.getPrincipal();
		        team.deletePrincipalTarget(theRole, principal);
		        PersistenceHelper.manager.refresh(team);
		      }
		    }
			
		}
	  }
	 
	 public static String getTypeNameNumber(WTObject primaryBusinessObject) {
			String TypeNameNumber = "";
			try {
				
					wt.fc.WTObject obj = (wt.fc.WTObject) primaryBusinessObject;
					
					if (obj instanceof WTDocument) {
						WTDocument doc = (WTDocument)obj;
						TypeNameNumber = ClientTypedUtility.getLocalizedTypeName((doc)).getLocalizedMessage(Locale.CHINA) + "," + doc.getName() + "," + doc.getContainerName().toString() + doc.getFolderPath().toString();
					
					}
				
			} catch (Exception e) {
				e.printStackTrace();
			}
			return TypeNameNumber;
		}
	 
	 /**
		 * 赋予用户访问该对象权限
		 * @param persistable
		 * @param wtprincipal
		 */
		public static void setObjectAccessModify(Persistable persistable,
				WTPrincipal wtprincipal,Vector paramVector) {
			boolean flag = SessionServerHelper.manager.setAccessEnforced(false);
			Transaction transaction = new Transaction();
			try {
				transaction.start();
				WTPrincipalReference paramWTPrincipalReference = WTPrincipalReference
						.newWTPrincipalReference(wtprincipal);
				persistable = PersistenceHelper.manager.refresh(persistable);
				if ((persistable instanceof AdHocControlled)) {
					AdHocControlled paramAdHocControlled = (AdHocControlled) persistable;
					//AdHocAccessKey paramAdHocAccessKey = AdHocAccessKey.WNC_LIFECYCLE;
					AdHocAccessKey paramAdHocAccessKey = AdHocAccessKey.WNC_ACCESS_CONTROL;
					paramAdHocControlled = AccessControlHelper.manager
							.addPermissions(paramAdHocControlled,
									paramWTPrincipalReference, paramVector,
									paramAdHocAccessKey);
					PersistenceServerHelper.manager.update(paramAdHocControlled,
							false);
				}
				transaction.commit();
				transaction = null;
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (transaction != null)
					transaction.rollback();
				SessionServerHelper.manager.setAccessEnforced(flag);
			}
		}
}
